﻿using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace ZBJF.Warranty.Common.Common
{
    public class FileHelper
    {
        public static string Read(string path)
        {
            var sr = new StreamReader(path, Encoding.Default);
            var text = sr.ReadToEnd();
            sr.Close();
            return text;
        }
        public static void Write(string path, string text)
        {
            var sr = new StreamWriter(path, false, Encoding.Default);
            sr.Write(text);
            sr.Close();
        }
        /// <summary>
        /// 格式化文件大小12G12M
        /// </summary>
        /// <param name="fileSize"></param>
        /// <returns></returns>
        public static string FormatFileSize(long fileSize)
        {
            if (fileSize > 1024 * 1024 * 1024)
                return fileSize / (1024 * 1024 * 1024) + "GB";
            else if (fileSize > 1024 * 1024)
                return fileSize / (1024 * 1024) + "MB";
            else if (fileSize > 1024)
                return fileSize / (1024) + "KB";
            else return fileSize + "B";
        }

        #region 保存文件 + static string UploadFile(HttpPostedFileBase file, HttpServerUtilityBase server, string folderName)
        /// <summary>
        /// 上传文件到网站相对路径/UploadFile/File/
        /// </summary>
        /// <param name="file">文件</param>
        /// <param name="server">web请求类帮助方法基类</param>
        /// <param name="FolderName">文件夹名称 例如: workOrder/20171214 </param>
        /// <returns></returns>
        public static string UploadFile(HttpPostedFileBase file, HttpServerUtilityBase server, string folderName)
        {
            if (file != null && file.ContentLength > 0)
            {
                string folder = "/UploadFile/File/" + folderName + "/";
                string dirPath = server.MapPath(folder);
                if (!Directory.Exists(dirPath))
                {
                    Directory.CreateDirectory(dirPath);
                }
                var fileName = GetNewFileName(dirPath, GetFileName(file.FileName));
                file.SaveAs(fileName);
                return folder + fileName;
            }
            return String.Empty;
        }

        #endregion


        #region 无损压缩图片 + static byte[] GetPicThumbnail(Stream fileStream, int flag)
        /// <summary>
        /// 无损压缩图片
        /// </summary>
        /// <param name="file">原图片</param>
        /// <param name="flag">压缩质量 1-100（传0表示自动设置质量值）</param>
        /// <param name="saveFullPath">文件保存绝对路径 /结尾</param>
        /// <returns></returns>
        public static bool GetPicThumbnail(HttpPostedFileBase file, int flag, string saveFullPath, string fileName)
        {
            using (System.Drawing.Image iSource = System.Drawing.Image.FromStream(file.InputStream))
            {
                if (flag < 1 || flag > 100)
                {
                    flag = GetImageCompressionQuality(file.ContentLength, iSource.Width, iSource.Height);
                }
                //以下代码为保存图片时，设置压缩质量
                EncoderParameters ep = new EncoderParameters();
                long[] qy = new long[1];
                qy[0] = flag;//设置压缩的比例1-100
                EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
                ep.Param[0] = eParam;
                ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo jpegICIinfo = null;
                for (int x = 0; x < arrayICI.Length; x++)
                {
                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
                    {
                        jpegICIinfo = arrayICI[x];
                        break;
                    }
                }
                if (!Directory.Exists(saveFullPath))
                {
                    Directory.CreateDirectory(saveFullPath);
                }
                try
                {
                    iSource.Save(saveFullPath + fileName, jpegICIinfo, ep);//saveFullPath是压缩后的新路径
                    return true;
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog("压缩图片保存失败" + ex, LogType.error);
                    return false;
                }
            }
        }

        #endregion

        #region 图片压缩质量值计算 + static int GetImageCompressionQuality(int fileSize,int width, int height)
        /// <summary>
        /// 图片压缩质量值计算
        /// </summary>
        /// <param name="fileSize">图片大小</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        /// <returns></returns>
        public static int GetImageCompressionQuality(int fileSize, int width, int height)
        {
            //假设标准质量为  width=500, height=300,size=300KB  也就是 150000 = 3KB  质量=100
            //int baseArea = 150000;
            //int baseSize = 300 * 1024;
            //int imageArea = width * height;
            //int quality =(int)( (imageArea * 1.0 / baseArea) * (baseSize * 1.0 / fileSize) * 100);
            //if (quality < 30)
            //    quality = 30;
            //else if (quality > 100)
            //    quality = 100;
            //return quality;

            if (fileSize > 5000 * 1024)
                return 40;
            else if (fileSize > 3000 * 1024)
                return 50;
            else if (fileSize > 2000 * 1024)
                return 60;
            else if (fileSize > 1500 * 1024)
                return 70;
            else if (fileSize > 1000 * 1024)
                return 80;
            else if (fileSize > 500 * 1024)
                return 90;
            else
                return 100;
        }
        #endregion

        #region 上传文件到网站相对路径/UploadFile/File/ + static string UploadFile(HttpPostedFileBase file, HttpServerUtilityBase server)
        /// <summary>
        /// 上传文件到网站相对路径/UploadFile/File/
        /// </summary>
        /// <param name="file">文件</param>
        /// <param name="server">web请求类帮助方法基类</param>
        /// <returns></returns>
        public static string UploadFile(HttpPostedFileBase file, HttpServerUtilityBase server)
        {
            if (file != null && file.ContentLength > 0)
            {
                string folder;
                string dirPath = GetUpLoadDirPath(server, out folder);
                var fileName = GetNewFileName(dirPath, GetFileName(file.FileName));
                file.SaveAs(dirPath + fileName);
                return folder + fileName;
            }
            return String.Empty;
        }
        #endregion

        #region 获取文件的名称 + static string GetFileName(string fileName)
        /// <summary>
        /// 获取文件的名称
        /// </summary>
        /// <param name="fileName">文件全路径</param>
        /// <returns></returns>
        private static string GetFileName(string fileName)
        {
            return fileName.Substring(fileName.LastIndexOf("\\", StringComparison.Ordinal) + 1);
        }
        #endregion

        #region 生成上传文件保存路径 + 生成上传文件保存路径 + static string GetUpLoadDirPath(HttpServerUtilityBase server, out string folder)
        /// <summary>
        /// 生成上传文件保存路径
        /// </summary>
        /// <param name="server"></param>
        /// <param name="folder">保存路径中的相对路径</param>
        /// <returns>保存路径中的绝对路径</returns>
        private static string GetUpLoadDirPath(HttpServerUtilityBase server, out string folder)
        {
            folder = GetUpLoadRelativePath();
            string dirPath = server.MapPath(folder);
            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }
            return dirPath;
        }
        /// <summary>
        /// 获取文件名（不包含扩展名）
        /// </summary>
        /// <returns></returns>
        public static string GetFileNameNoExtension(string fileName)
        {
            if (string.IsNullOrWhiteSpace(fileName))
                return string.Empty;
            var index = fileName.LastIndexOf('/');
            var lastIndex = fileName.LastIndexOf('.');
            return fileName.Substring(index + 1, lastIndex - index - 1);
        }

        public static string GetUpLoadRelativePath()
        {
            return "/UploadFile/File/" + DateTime.Now.ToString("yyyy/MM/dd", DateTimeFormatInfo.InvariantInfo) + "/";
        }
        #endregion

        #region 获取一个新的文件名称 + static string GetNewFileName(string dirPath, string fileName)
        /// <summary>
        /// 获取一个新的文件名称
        /// </summary>
        /// <param name="dirPath">文件路径</param>
        /// <param name="fileName">文件名称</param>
        /// <returns></returns>
        private static string GetNewFileName(string dirPath, string fileName)
        {
            string newFileName;
            var strFileExt = fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal) + 1);
            if (File.Exists(dirPath + fileName))
            {
                newFileName = fileName.Substring(0, fileName.LastIndexOf('.')) + "_1." + strFileExt;
                newFileName = GetNewFileName(dirPath, newFileName);
            }
            else
            {
                newFileName = fileName;
            }
            return newFileName;
        }
        #endregion

        #region 压缩图片 + static bool ReduceImage(Image iSource, string outPath, int flag)
        /// <summary>
        /// 压缩图片
        /// </summary>
        /// <param name="iSource">图片文件</param>
        /// <param name="outPath">路径</param> 例如 var outPath = Path.Combine(Request.MapPath("~/Upload"), Path.GetFileName(file.FileName));
        /// <param name="flag">值越大代表图片质量越好，一般默认控制在50为最佳压缩质量</param>
        /// <returns></returns>
        public static bool ReduceImage(Image iSource, string outPath, int flag)
        {
            ImageFormat tFormat = iSource.RawFormat;
            EncoderParameters ep = new EncoderParameters();
            long[] qy = new long[1];
            qy[0] = flag;
            EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
            ep.Param[0] = eParam;
            try
            {
                ImageCodecInfo[] arrayIci = ImageCodecInfo.GetImageDecoders();
                ImageCodecInfo jpegIcIinfo = arrayIci.FirstOrDefault(t => t.FormatDescription.Equals("JPEG"));
                if (jpegIcIinfo != null)
                    iSource.Save(outPath, jpegIcIinfo, ep);
                else
                    iSource.Save(outPath, tFormat);
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                iSource.Dispose();
            }
        }
        #endregion

        #region 将base64编码的字符串转为图片并保存 + static string SaveBase64Image(string source, string path)

        ///  <summary>
        /// 将base64编码的字符串转为图片并保存
        ///  </summary>
        ///  <param name="server"></param>
        ///  <param name="source">base64图片名</param>
        /// <param name="path">相对路径</param>
        /// <param name="absulotePath">返回绝对路径</param>
        /// <returns></returns>
        public static string SaveBase64Image(string source, string path, out string absulotePath)
        {
            try
            {
                var now = DateTime.Now;
                string filePath = path;
                string fileName = now.ToString("yyyyMMddhhmmssffff") + ".png";
                string strbase64 = source.Substring(source.IndexOf(',') + 1);
                strbase64 = strbase64.Trim('\0');
                byte[] arr = Convert.FromBase64String(strbase64);
                using (MemoryStream ms = new MemoryStream(arr))
                {
                    Bitmap bmp = new Bitmap(ms);
                    absulotePath = System.Web.HttpContext.Current.Server.MapPath(filePath);
                    if (!Directory.Exists(absulotePath) && !string.IsNullOrEmpty(absulotePath))
                    {
                        Directory.CreateDirectory(absulotePath);
                    }
                    //新建第二个bitmap类型的bmp2变量。
                    Bitmap bmp2 = new Bitmap(bmp, bmp.Width, bmp.Height);
                    //将第一个bmp拷贝到bmp2中
                    Graphics draw = Graphics.FromImage(bmp2);
                    draw.DrawImage(bmp, 0, 0);
                    draw.Dispose();
                    //ReduceImage:先压缩图片
                    System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);
                    string url = "";
                    if (ReduceImage(image, System.Web.HttpContext.Current.Server.MapPath(filePath + fileName), 50))
                    {
                        url = filePath + fileName;
                    }
                    ms.Close();
                    return url;
                }
            }
            catch (Exception ex)
            {
                absulotePath = System.Web.HttpContext.Current.Server.MapPath(path);
                return source;
            }
        }
        #endregion

        #region 获取图片的大小和尺寸 + static void GetImageInfo(string aPhotoUrl, ref string aSize, ref string aLength)
        /// <summary> 
        /// 获取图片的大小和尺寸 
        /// </summary> 
        /// <param name="aPhotoUrl">图片url</param> 
        /// <param name="iSize">图片大小</param> 
        /// <param name="aLength">图片尺寸</param> 
        public static void GetImageInfo(string aPhotoUrl, ref long iSize, ref string aLength)
        {
            try
            {
                Uri mUri = new Uri(aPhotoUrl);
                FileWebRequest mRequest = (FileWebRequest)WebRequest.Create(mUri);
                mRequest.Method = "GET";
                mRequest.Timeout = 200;
                mRequest.ContentType = "text/html;charset=utf-8";
                FileWebResponse mResponse = (FileWebResponse)mRequest.GetResponse();
                Stream mStream = mResponse.GetResponseStream();
                iSize = mResponse.ContentLength;
                Image mImage = Image.FromStream(mStream);
                aLength = mImage.Width.ToString() + "x" + mImage.Height.ToString();
                mStream.Close();
            }
            catch (Exception e)
            {
                //MessageBox.Show(aPhotoUrl + "获取失败"); 
            }
        }
        #endregion

        #region 文件夹批量压缩 + static async Task ZipFile(string[] strFile, string strDirectory, string fileName)
        /// <summary>
        /// 文件夹批量压缩
        /// </summary>
        /// <param name="strFile">文件夹数组</param>
        /// <param name="strDirectory">保存路径 不以/结尾</param>
        /// <param name="fileName">文件名称</param>
        public static async Task ZipFile(string[] strFile, string strDirectory, string fileName)
        {
            if (!Directory.Exists(strDirectory))
            {
                Directory.CreateDirectory(strDirectory);
            }
            string strZip = strDirectory + "/" + fileName;
            await Task.Factory.StartNew(() =>
            {
                ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(strZip));
                s.SetLevel(6);
                for (int i = 0, j = strFile.Length; i < j; i++)
                {
                    string item = strFile[i];
                    if (!Directory.Exists(item))
                    {
                        continue;
                    }
                    Zip(item, s, item);
                }
                s.Finish();
                s.Close();
            });
        }

        private static void Zip(string strFile, ZipOutputStream s, string staticFile)
        {
            Crc32 crc = new Crc32();
            string[] filenames = Directory.GetFileSystemEntries(strFile);
            foreach (string file in filenames)
            {

                if (Directory.Exists(file))
                {
                    Zip(file, s, staticFile);
                }

                else // 否则直接压缩文件
                {
                    //打开压缩文件
                    FileStream fs = System.IO.File.OpenRead(file);

                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    string tempfile = file.Substring(staticFile.LastIndexOf("\\", StringComparison.Ordinal) + 1);
                    ZipEntry entry = new ZipEntry(tempfile)
                    {
                        DateTime = DateTime.Now,
                        Size = fs.Length
                    };

                    fs.Close();
                    crc.Reset();
                    crc.Update(buffer);
                    entry.Crc = crc.Value;
                    s.PutNextEntry(entry);

                    s.Write(buffer, 0, buffer.Length);
                }
            }
        }
        #endregion

        #region 判断文件是否是可用状态 + static bool ReadFileStream(string path)
        /// <summary>
        /// 判断文件是否是可用状态
        /// </summary>
        /// <param name="path">文件绝对地址</param>
        /// <returns></returns>
        public static bool ReadFileStream(string path)
        {
            if (!File.Exists(path)) //如果文件还没有被压缩好则等待一会
            {
                return false;
            }
            else
            {
                try
                {
                    Stream stream = File.Open(path, FileMode.Open);
                    stream.Dispose();
                    stream.Close();
                    return true;
                }
                catch
                {
                    return false;
                }
            }

        }
        #endregion

        #region 获取网络路径的图片保存到本地 + static string SaveNetworkImage(string url, string filePath, string fileName,bool isAbsolutePath=false)
        /// <summary>
        /// 获取网络路径的图片保存到本地
        /// </summary>
        /// <param name="url">图片的网络地址</param>
        /// <param name="filePath">保存路径</param>
        /// <param name="fileName">文件名称</param>
        /// <param name="isAbsolutePath">保存路径是否是绝对路径</param>
        /// <returns>图片本地路径</returns>
        public static string SaveNetworkImage(string url, string filePath, string fileName, bool isAbsolutePath = false)
        {
            try
            {
                System.Net.WebRequest webreq = System.Net.WebRequest.Create(url);
                System.Net.WebResponse webres = webreq.GetResponse();
                using (System.IO.Stream stream = webres.GetResponseStream())
                {
                    Image image = Image.FromStream(stream);
                    string path = filePath;
                    if (!isAbsolutePath)
                        path = System.Web.HttpContext.Current.Server.MapPath(filePath);
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    image.Save(path + fileName);
                }
                return filePath + fileName;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("获取网络路径的图片保存到本地异常:" + ex.ToString(), LogType.error);
            }
            return "";
        }
        #endregion

        #region 改变文件的后缀名 + string ChangeFileExten(string fileName,string exten)
        /// <summary>
        /// 改变文件的后缀名
        /// </summary>
        /// <param name="fileName">原文件名</param>
        /// <param name="exten">新后缀名（.mp3）</param>
        /// <returns></returns>
        public static string ChangeFileExten(string fileName, string exten)
        {
            return Path.ChangeExtension(fileName, exten);
        }
        #endregion

        #region 文件移动 + static bool MoveFile(string resouceFile,string targetFilePath,string targetFileName)
        /// <summary>
        /// 文件移动
        /// </summary>
        /// <param name="resouceFile">原文件绝对地址</param>
        /// <param name="targetFilePath">目标文件夹绝对地址（/结尾）</param>
        /// <param name="targetFileName">目标文件名称</param>
        /// <returns></returns>
        public static bool MoveFile(string resouceFile, string targetFilePath, string targetFileName)
        {
            if (!File.Exists(resouceFile))
                return false;
            if (!Directory.Exists(targetFilePath))
            {
                Directory.CreateDirectory(targetFilePath);
            }
            try
            {
                File.Move(resouceFile, targetFilePath + targetFileName);
                return true;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("文件移动失败：原文件名：" + resouceFile + "；目标地址：" + targetFilePath + targetFileName + "；异常：" + ex.ToString(), LogType.error);
            }
            return false;
        }
        #endregion
    }
}
